GLOBAL.setmetatable(env, {
    __index = function(k, v)
        return GLOBAL.rawget(GLOBAL, v)
    end
})

local replace_actions = {ACTIONS.WALKTO, ACTIONS.LOOKAT}
local e_util = require "libs/entutil"
local t_util = require "libs/tableutil"
local s_mana = require "libs/settingmanager"
local save_id = "click_to_switch"
local turnon
local p_util = require "libs/playerutil"

AddPlayerActivatedFunc(function(player, world)
    local PC = player.components.playercontroller
    local PI = player.components.playeractionpicker
    if not PC or not PI then
        return
    end
    turnon = s_mana:GetSettingLine(save_id).turnon
    turnon = type(turnon) == "nil" and true or turnon

    local function CanReplaceLeft(act, ctrl)
        local target = act and act.target
        if target and (table.contains(replace_actions, act.action) or
            (act.action == ACTIONS.ATTACK and target:HasOneOfTags({"butterfly", "bee", "firefly"}))) and not ctrl then
            return p_util:GetItemFromAll(nil, nil, function(item)
                if e_util:GetItemEquipSlot(item) == EQUIPSLOTS.HANDS then
                    local hand = p_util:GetEquip(EQUIPSLOTS.HANDS)
                    if hand and hand.prefab == item.prefab then
                        -- 其实完全可以不用这一步，但是谁知道会有什么突发情况呢
                        return
                    end
                    -- TODO:这里会决定究竟切哪个装备，使用哪个动作，但我目前并没有设计顺序和优先级
                    local _, newact = next(PI:GetUseItemActions(target, item, false))
                    return newact and not table.contains(replace_actions, newact.action)
                end
            end, {"body", "backpack", "container"})
        end
    end

    local _OnLeftClick = PC.OnLeftClick
    function PC:OnLeftClick(down)
        if not turnon or not self:UsingMouse() or not down or not self:IsEnabled() or TheInput:GetHUDEntityUnderMouse() or
            (self.placer_recipe and self.placer) or not TheInput:GetWorldEntityUnderMouse() 
            or self:IsAOETargeting()  then
            return _OnLeftClick(self, down)
        end
        self:ClearActionHold()

        local act = self:GetLeftMouseAction() or BufferedAction(self.inst, nil, ACTIONS.WALKTO, nil, TheInput:GetWorldPosition())

        local equip_left = CanReplaceLeft(act, self:EncodeControlMods())
        if equip_left then
            p_util:Equip(equip_left)
            self.inst:DoTaskInTime(0.2, function()
                _OnLeftClick(self, down)
            end)
        else
            return _OnLeftClick(self, down)
        end
    end

    local _OnRightClick = PC.OnRightClick
    function PC:OnRightClick(down)
        if not turnon or not self:UsingMouse() or not down or self.placer_recipe or self:IsAOETargeting() or
            not self:IsEnabled() or TheInput:GetHUDEntityUnderMouse() or not TheInput:GetWorldEntityUnderMouse() then
            return _OnRightClick(self, down)
        end
        self:ClearActionHold()
        local right_test
        local act = self:GetRightMouseAction()
        if not act then
            if not p_util:GetActiveItem() then
                local item = p_util:GetEquip(EQUIPSLOTS.HANDS)
                if not (item and item.components.aoetargeting and item.components.aoetargeting:IsEnabled()) then
                    right_test = true
                end
            end
        elseif act.invobject ~= nil and act.invobject:HasTag("action_pulls_up_map") then
        elseif table.contains(replace_actions, act.action) or
            (act.action == ACTIONS.FILL and e_util:GetPercent(p_util:GetEquip(EQUIPSLOTS.HANDS)) > 99) then
            right_test = true
        end

        if right_test and not self:EncodeControlMods() then
            local target = act and act.target or TheInput:GetWorldEntityUnderMouse()
            if target then
                local equip_right = p_util:GetItemFromAll(nil, nil, function(item)
                    if e_util:GetItemEquipSlot(item) == EQUIPSLOTS.HANDS then
                        local _, newact = next(PI:GetUseItemActions(target, item, true))
                        return newact and
                                   (not table.contains(t_util:MergeList(replace_actions, {ACTIONS.FILL}), newact.action) or
                                       (newact.action == ACTIONS.FILL and e_util:GetPercent(item) < 100))
                    end
                end, {"body", "backpack", "container"})
                if equip_right then
                    p_util:Equip(equip_right)
                    self.inst:DoTaskInTime(0.2, function()
                        _OnRightClick(self, down)
                    end)
                    return
                end
            end
        end
        return _OnRightClick(self, down)
    end
end)

local function fn()
    turnon = not turnon
    s_mana:SaveSettingLine(save_id, {
        turnon = turnon
    })
    TIP("点击切装备", "white", turnon)
end

if GetModConfigData("sw_click") == "biubiu" then
    DEAR_BTNS:AddDearBtn(GLOBAL.GetInventoryItemAtlas("bodypillow_petals.tex"), "bodypillow_petals.tex",
                         "点击切装备", "修改【检查】【走向】两个动作", true, fn)
end
AddBindBtn("sw_click", fn)
